#include "StdAfx.h"
#include "Hash.h"

#define HASHSIZE 101

struct hashlist_s
{
	hashlist_s *next;
	string name;
	void * addr;
};
typedef struct hashlist_s hashlist_t;

static hashlist_t * hashtab[HASHSIZE];

void hs_delete();

int hs_init(int size)
{
	return 1;
}
void hs_exit( void )
{
	hs_delete();
}

unsigned int hs_hash(string str )
{
	unsigned int hashval;
	const char * s= str.c_str();

	for (hashval =0; *s != '\0'; s++)
	{
		hashval = *s + 31 * hashval;
	}
	return hashval % HASHSIZE;
}
void * hs_find(string s )
{
	hashlist_t * np;

	for ((np=hashtab[hs_hash(s)]); np != NULL; np = np->next )
	{
		if( np->name == s )
			return np->addr;
	}
	return NULL;
}
hashlist_t * hs_lookup(string s )
{
	hashlist_t * np;

	for ((np=hashtab[hs_hash(s)]); np != NULL; np = np->next )
	{
		if( np->name == s )
			return np;
	}
	return NULL;
}
bool hs_add( string name, void * addr)
{
	hashlist_t *np;
	unsigned int hashval;

	hashval = hs_hash(name);
	np = hashtab[hashval];
	if ( np == NULL)
	{
		np = new hashlist_t;	TRACE(_T("=== hs_add np new: 0x%x\n"), np);
		np->next = NULL;
		np->addr = addr;
		np->name = name;
		hashtab[hashval] = np;

		return true;
	}
	else
	{
		do 
		{
			if (np->name == name)
			{
				return false;
			}
			if (np->next == NULL)	// add to the end of the list;
			{
				hashlist_t * hl = new hashlist_t;	TRACE(_T("=== hashlist new: 0x%x\n"), (int)hl);
				hl->next = NULL;
				hl->name = name;
				hl->addr = addr;

				np->next = hl;

				break;
			}
			else
				np = np->next;
		} while (np!=NULL);
	}
	return true;
}

void hs_delete()
{
	hashlist_t * np;
	hashlist_t * tp;

	for (int i = 0; i < HASHSIZE; i++)
	{
		np = hashtab[i];
		while ( np != NULL)
		{
			tp = np;
			np = np->next;
			delete tp;
		}
	}
}